package com.wwl.controller;

import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.net.ssl.SSLException;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.image.util.ImageUtils;
import com.image.util.ImgCompress;

@Controller
@RequestMapping("/face")
public class DetectionFaceController {
	
	Logger logger = Logger.getLogger(DetectionFaceController.class);
	String detection="/home/apache-tomcat-7.0.47/webapps/image/detection/";	
	
	/**
	 *检测用户上传的图片是否符合人脸检测接口的标准
	 */
	@ResponseBody
	@SuppressWarnings("deprecation")
	@RequestMapping(value="/detection",method=RequestMethod.POST)
	public String detection(@RequestParam MultipartFile file,HttpServletResponse response) throws Exception{
		String fileName = file.getOriginalFilename();					
		String str_fileName = fileName.substring(fileName.indexOf("."));
		Date data = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String newData = dateFormat.format(data);
        String name = newData + str_fileName;
        File targetFile = new File(detection+name);
        if(!targetFile.exists()){  
            targetFile.mkdirs();  
        }  
        try { 
            file.transferTo(targetFile); 
        } catch (Exception e) {  
            e.printStackTrace();  
        }					
	    try {  
	        logger.info("前端请求图片名:" + name);
	        BufferedImage src = ImageIO.read(targetFile);
	        BufferedImage  bi = null;
	        if(src != null){  
	            //获取图片旋转角度  
	            int angel = ImageUtils.getRotateAngleForPhoto(detection,name);  
	            if(angel == 0){  
	                //图片正常，不处理图片  
	                bi = src;  
	                //图片压缩
        	        ImgCompress.setFile(detection+ name);			
        	        logger.info("开始：" + new Date().toLocaleString());  
        	        ImgCompress imgCom = new ImgCompress(detection+name);  
        	        imgCom.resizeFix(400, 400); 
        	        logger.info("结束：" + new Date().toLocaleString()); 
	            }else{  
	                //图片被翻转，调整图片 
	                int src_width = src.getWidth(null);  
	                int src_height = src.getHeight(null);  
	                Rectangle rect_des = ImageUtils.CalcRotatedSize(new Rectangle(new Dimension(src_width, src_height)), angel);  
	                bi = new BufferedImage(rect_des.width, rect_des.height,BufferedImage.TYPE_INT_RGB);  
	                Graphics2D g2 = bi.createGraphics();  
	                g2.translate((rect_des.width - src_width) / 2,  
	                            (rect_des.height - src_height) / 2);  
	                g2.rotate(Math.toRadians(angel), src_width / 2, src_height / 2);  
	                g2.drawImage(src, null, null);  
	            }  
	            File files = new File(detection+name);
	    		byte[] buff = getBytesFromFile(files);
	    		String url = "https://api-cn.faceplusplus.com/facepp/v3/detect";
	            HashMap<String, String> map = new HashMap();
	            HashMap<String, byte[]> byteMap = new HashMap();
	            map.put("api_key", "mDyC2jSC_Mlpp8ZU9vp7VL5olqO4tsWl");
	            map.put("api_secret", "7L5mhuPM7KYUYCb0vb-WnN-F6dLzc5Jx");
	            byteMap.put("image_file", buff);
	            try{
	                byte[] bacd = post(url, map, byteMap);
	                String str = new String(bacd);
	                logger.info("人脸识别检测返回参数:"+str);
	                String substring=str.substring(1,5);			
	                if(substring.equals("html")){				//图片超出2MB处理,提示用户
	                	String index=str.substring(21,24);
	                	logger.info("图片超出2MB处理:"+index);
	                	return index;
	                }else{
	                	return str.toString();
	                }
	            }catch (Exception e) {
	            	e.printStackTrace();
	            	logger.info(e);
	            	return "0";
	    		}
	        }else{  
	            //图片不存在  
	            logger.info("图片：" + name + "为空");  
	        }  
	    } catch (Exception e) {  
	        e.printStackTrace();
	    }
	    return null;
	}
	private final static int CONNECT_TIME_OUT = 30000;
    private final static int READ_OUT_TIME   =  50000;
    private static String boundaryString = getBoundary();
    protected static byte[] post(String url, HashMap<String, String> map, HashMap<String, byte[]> fileMap) throws Exception {
        HttpURLConnection conne;
        URL url1 = new URL(url);
        conne = (HttpURLConnection) url1.openConnection();
        conne.setDoOutput(true);
        conne.setUseCaches(false);
        conne.setRequestMethod("POST");
        conne.setConnectTimeout(CONNECT_TIME_OUT);
        conne.setReadTimeout(READ_OUT_TIME);
        conne.setRequestProperty("accept", "*/*");
        conne.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundaryString);
        conne.setRequestProperty("connection", "Keep-Alive");
        conne.setRequestProperty("user-agent", "Mozilla/4.0 (compatible;MSIE 6.0;Windows NT 5.1;SV1)");
        DataOutputStream obos = new DataOutputStream(conne.getOutputStream());
        Iterator iter = map.entrySet().iterator();
        while(iter.hasNext()){
            Map.Entry<String, String> entry = (Map.Entry) iter.next();
            String key = entry.getKey();
            String value = entry.getValue();
            obos.writeBytes("--" + boundaryString + "\r\n");
            obos.writeBytes("Content-Disposition: form-data; name=\"" + key
                    + "\"\r\n");
            obos.writeBytes("\r\n");
            obos.writeBytes(value + "\r\n");
        }
        if(fileMap != null && fileMap.size() > 0){
            Iterator fileIter = fileMap.entrySet().iterator();
            while(fileIter.hasNext()){
                Map.Entry<String, byte[]> fileEntry = (Map.Entry<String, byte[]>) fileIter.next();
                obos.writeBytes("--" + boundaryString + "\r\n");
                obos.writeBytes("Content-Disposition: form-data; name=\"" + fileEntry.getKey()
                        + "\"; filename=\"" + encode(" ") + "\"\r\n");
                obos.writeBytes("\r\n");
                obos.write(fileEntry.getValue());
                obos.writeBytes("\r\n");
            }
        }
        obos.writeBytes("--" + boundaryString + "--" + "\r\n");
        obos.writeBytes("\r\n");
        obos.flush();
        obos.close();
        InputStream ins = null;
        int code = conne.getResponseCode();
        try{
            if(code == 200){
                ins = conne.getInputStream();
            }else{
                ins = conne.getErrorStream();
            }
        }catch (SSLException e){
            e.printStackTrace();
            return new byte[0];
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buff = new byte[4096];
        int len;
        while((len = ins.read(buff)) != -1){
            baos.write(buff, 0, len);
        }
        byte[] bytes = baos.toByteArray();
        ins.close();
        return bytes;
    }
    private static String getBoundary() {
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for(int i = 0; i < 32; ++i) {
            sb.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-".charAt(random.nextInt("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_".length())));
        }
        return sb.toString();
    }
    private static String encode(String value) throws Exception{
        return URLEncoder.encode(value, "UTF-8");
    }
    public static byte[] getBytesFromFile(File f) {
        if (f == null) {
            return null;
        }
        try {
            FileInputStream stream = new FileInputStream(f);
            ByteArrayOutputStream out = new ByteArrayOutputStream(1000);
            byte[] b = new byte[1000];
            int n;
            while ((n = stream.read(b)) != -1)
                out.write(b, 0, n);
            stream.close();
            out.close();
            return out.toByteArray();
        } catch (IOException e) {
        }
        return null;
    }
}
